#ifndef THREAD_H
#define THREAD_H

#ifdef UNIX
# include <unistd.h>
# ifdef _POSIX_THREADS
#  define USE_POSIX_THREADS
# else
#  define NO_THREAD /* posix threads not supported: threads disabled */
# endif
#else
# define USE_POSIX_THREADS
#endif

#ifdef USE_POSIX_THREADS
# include <pthread.h>
# ifdef UNIX
#  include <sys/time.h>
#  include <errno.h>
# else
#  include <windows.h>
# endif
# define TH_TYPE void*
# define TH_RET void*
# define FUNC_TYPE void *(*function)(void *)
#endif

#ifndef NO_THREAD

#include "log.h"

#define COND_TIMEOUT 0
#define COND_MET 1

typedef struct
{
    pthread_mutex_t mutex;
    char name[32];
} Mutex;

typedef struct
{
    pthread_t thread_id;
} Thread;

typedef struct
{
    Mutex mtx;
    pthread_cond_t cond;
    u32 nsec;
    u32 sec;
} Condition;

void thread_init(Thread *thr, FUNC_TYPE, void* arg);
void thread_waitForDeath(Thread *thr);
void thread_stop(Thread *thr);
u8 thread_isActual(Thread *thr);

Condition *thread_cond_init(u32 wait_ms);
s8 thread_cond_timedWait(Condition *cond, Mutex *mtx);
void thread_cond_wait(Condition *cond, Mutex *mtx);
void thread_cond_signal(Condition *cond);
void thread_cond_free(Condition *cond);

void cs_init(Mutex *cs, const char name[32]);
void cs_free(Mutex *cs);
void cs_enter(Mutex *cs);
void cs_leave(Mutex *cs);

#else /* NO_THREAD */

#define cs_enter(arg)
#define cs_leave(arg)

#endif

#endif /* THREAD_H */

